package oss

import (
	"context"
	"encoding/json"
	"errors"
	"gitee.com/dsler-go/utils/servers/redis"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	sts20150401 "github.com/alibabacloud-go/sts-20150401/v2/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
	"time"
)

type StsConfig struct {
	StsUri             string `ini:"sts_uri"`
	StsAccessid        string `ini:"sts_accessid"`
	StsAccesskey       string `ini:"sts_accesskey"`
	StsEndpoint        string `ini:"sts_endpoint"`
	StsRoleArn         string `ini:"sts_role_arn"`
	StsRoleSessionName string `ini:"sts_role_session_name"`
}

var DefaultStsClient = &StsConfig{}

func InitAliSts(stsUri, stsAccessid, stsAccesskey, stsEndpoint, stsRoleArn, stsRoleSessionName string) {
	DefaultStsClient.StsUri = stsUri
	DefaultStsClient.StsAccessid = stsAccessid
	DefaultStsClient.StsAccesskey = stsAccesskey
	DefaultStsClient.StsEndpoint = stsEndpoint
	DefaultStsClient.StsRoleArn = stsRoleArn
	DefaultStsClient.StsRoleSessionName = stsRoleSessionName
}

/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return Client
 * @throws Exception
 */
func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *sts20150401.Client, _err error) {
	clientConfig := &openapi.Config{
		// 必填，您的 AccessKey ID
		AccessKeyId: accessKeyId,
		// 必填，您的 AccessKey Secret
		AccessKeySecret: accessKeySecret,
	}
	// Endpoint 请参考 https://api.aliyun.com/product/Sts
	clientConfig.Endpoint = tea.String(DefaultStsClient.StsEndpoint)
	_result = &sts20150401.Client{}
	_result, _err = sts20150401.NewClient(clientConfig)
	return _result, _err
}

func GetStsToken() (*sts20150401.AssumeRoleResponseBodyCredentials, error) {
	key := "dsler:sts:dpfsUTjKu3TzKksLEDVU"
	str, err := redis.DefaultRedisV8.Client.Get(context.Background(), key).Result()
	if err == nil {
		r := &sts20150401.AssumeRoleResponseBodyCredentials{}
		err := json.Unmarshal([]byte(str), r)
		if err != nil {
			return nil, err
		}
		return r, nil
	} else {
		res, err := getStsTokenByAli()
		if err != nil {
			return nil, err
		}
		if res != nil && res.Body != nil && res.Body.Credentials != nil {
			bStr, err := json.Marshal(res.Body.Credentials)
			if err != nil {
				return nil, err
			}
			redis.DefaultRedisV8.Client.Set(context.Background(), key, string(bStr), 3590*time.Second)
			return res.Body.Credentials, nil
		}

	}
	return nil, errors.New("请稍后重试")
}

func getStsTokenByAli() (*sts20150401.AssumeRoleResponse, error) {
	client, _err := CreateClient(tea.String(DefaultStsClient.StsAccessid), tea.String(DefaultStsClient.StsAccesskey))
	if _err != nil {
		return nil, _err
	}

	assumeRoleRequest := &sts20150401.AssumeRoleRequest{
		//DurationSeconds: tea.Int64(1),
		//Policy:          tea.String("{\n    \"Version\": \"1\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": \" oss:*\",\n            \"Resource\": [\n                \"acs:oss:*:*:ywfwl\",\n                \"acs:oss:*:*:ywfwl/*\"\n            ]\n        }\n    ]\n}"),
		RoleArn:         tea.String(DefaultStsClient.StsRoleArn),
		RoleSessionName: tea.String(DefaultStsClient.StsRoleSessionName),
	}
	res, tryErr := func() (res *sts20150401.AssumeRoleResponse, _e error) {
		defer func() {
			if r := tea.Recover(recover()); r != nil {
				_e = r
			}
		}()
		// 复制代码运行请自行打印 API 的返回值
		res, _err := client.AssumeRoleWithOptions(assumeRoleRequest, &util.RuntimeOptions{})
		if _err != nil {
			return nil, _err
		}
		return res, nil
	}()
	if tryErr != nil {
		var err = &tea.SDKError{}
		if _t, ok := tryErr.(*tea.SDKError); ok {
			err = _t
		} else {
			err.Message = tea.String(tryErr.Error())
		}
		// 如有需要，请打印 error
		_, _err = util.AssertAsString(err.Message)
		if _err != nil {
			return nil, _err
		}
	}
	return res, nil
}
